<template>
  <div class="select-container">
    <!-- 遮罩层 -->
    <div class="mask" @click="cancel" :class="{ active: isShow }"></div>

    <!-- 弹窗 -->
    <div class="area_popup" :class="{ active: isShow }">
      <!-- 弹窗头部 -->
      <div class="area_popup_header">
        <span @click="cancel">取消</span>
        <span @click="confirm">确认</span>
      </div>

      <!-- 三列选择器 -->
      <div class="select-row">
        <!-- 省份列 -->
        <div class="select-col">
          <div class="select-viewport" :style="{ height: selectHeight + 'px' }">
            <div class="options-wrapper" :style="{ transform: `translateY(${provinceTranslateY}px)` }"
              @touchstart="onTouchStart($event, 'province')" @touchmove="onTouchMove($event, 'province')"
              @touchend="onTouchEnd($event, 'province')">
              <div v-for="(option, index) in displayProvinces" :key="option.value" class="option"
                :class="{ selected: selectedProvinceIndex === index }" @click="selectProvince(index)"
                ref="provinceOptions">
                {{ option.label }}
              </div>
            </div>
          </div>
        </div>

        <!-- 市列 -->
        <div v-if="showCityColumn" class="select-col">
          <div class="select-viewport" :style="{ height: selectHeight + 'px' }">
            <div class="options-wrapper" :style="{ transform: `translateY(${cityTranslateY}px)` }"
              @touchstart="onTouchStart($event, 'city')" @touchmove="onTouchMove($event, 'city')"
              @touchend="onTouchEnd($event, 'city')">
              <div v-for="(option, index) in displayCities" :key="option.value" class="option"
                :class="{ selected: selectedCityIndex === index }" @click="selectCity(index)" ref="cityOptions">
                {{ option.label }}
              </div>
            </div>
          </div>
        </div>

        <!-- 区列 -->
        <div v-if="showAreaColumn" class="select-col">
          <div class="select-viewport" :style="{ height: selectHeight + 'px' }">
            <div class="options-wrapper" :style="{ transform: `translateY(${areaTranslateY}px)` }"
              @touchstart="onTouchStart($event, 'area')" @touchmove="onTouchMove($event, 'area')"
              @touchend="onTouchEnd($event, 'area')">
              <div v-for="(option, index) in displayAreas" :key="option.value" class="option"
                :class="{ selected: selectedAreaIndex === index }" @click="selectArea(index)" ref="areaOptions">
                {{ option.label }}
              </div>
            </div>
          </div>
        </div>

        <!-- 分隔线 -->
        <div class="select-line" :class="{ 'show-area': showAreaColumn }"></div>
      </div>
    </div>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  name: 'AreaSelector',
  props: {
    isShow: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['update:isShow', 'confirm'],
  data() {
    return {
      selectHeight: 150,
      optionHeight: 40,

      // 当前选中索引
      selectedProvinceIndex: 0,
      selectedCityIndex: 0,
      selectedAreaIndex: 0,

      // 数据源：全部由内部维护
      provinces: [],
      cities: [],
      areas: [],

      showCityColumn: false,
      showAreaColumn: false,
      // 触摸相关
      startY: 0,
      startTime: 0,
      currentTranslateY: 0,
      isDragging: false,
      activeColumn: null, // 当前操作的列：'province' | 'city' | 'area'
      touchSensitivity: 0.8, // 滑动灵敏度
    };
  },
  mounted() {
    this.loadProvinces();
  },
  computed: {
    isIOS() {
      return /iPad|iPhone|iPod/.test(navigator.userAgent);
    },
    isAndroid() {
      return /Android/.test(navigator.userAgent);
    },
    alignOffsetRatio() {
      // 可以扩展更多设备判断
      if (this.isIOS) return 1.52;
      if (this.isAndroid) return 1;
      return 1.4; // 默认
    },
    displayProvinces() {
      return [
        { value: '', label: '请选择', placeholder: true },
        ...this.provinces,
      ];
    },
    displayCities() {
      return [
        { value: '', label: '请选择', placeholder: true },
        ...this.cities,
      ];
    },
    displayAreas() {
      return [{ value: '', label: '请选择', placeholder: true }, ...this.areas];
    },
    provinceTranslateY() {
      return this.getTranslateY(
        this.selectedProvinceIndex,
        this.displayProvinces.length
      );
    },
    cityTranslateY() {
      return this.getTranslateY(
        this.selectedCityIndex,
        this.displayCities.length
      );
    },
    areaTranslateY() {
      return this.getTranslateY(
        this.selectedAreaIndex,
        this.displayAreas.length
      );
    },
  },
  methods: {
    onTouchStart(e, column) {
      this.isDragging = true;
      this.activeColumn = column;
      this.startY = e.touches[0].clientY;
      this.startTime = Date.now();

      // 清除动画
      const wrapper = e.currentTarget;
      wrapper.style.transition = 'none';

      // 获取当前 translateY
      const computed = window.getComputedStyle(wrapper);
      const matrix = new WebKitCSSMatrix(computed.transform);
      this.currentTranslateY = matrix.m42;

      // ✅ 新增：记录上次移动时间 & 速度队列（用于计算动量）
      this.lastMoveTime = this.startTime;
      this.lastMoveY = this.startY;
      this.velocity = 0; // 当前滑动速度
      this.velocitySamples = []; // 速度样本（可选：平滑处理）
    },
    onTouchMove(e) {
      if (!this.isDragging) return;
      e.preventDefault();

      const moveY = e.touches[0].clientY;
      const deltaY = moveY - this.lastMoveY;
      const deltaTime = Date.now() - this.lastMoveTime;

      // ✅ 计算瞬时速度（px/ms）
      if (deltaTime > 0) {
        const velocity = deltaY / deltaTime;
        // 保留最近几次速度，用于平滑（可选）
        this.velocitySamples.push(velocity);
        if (this.velocitySamples.length > 3) {
          this.velocitySamples.shift();
        }
        this.velocity = this.velocitySamples.reduce((a, b) => a + b, 0) / this.velocitySamples.length;
      }

      // 累加位移
      this.currentTranslateY += deltaY * this.touchSensitivity;
      this.lastMoveY = moveY;
      this.lastMoveTime = Date.now();

      // 更新 transform
      const wrapper = e.currentTarget;
      wrapper.style.transform = `translateY(${this.currentTranslateY}px)`;
    },
    onTouchEnd(e) {
      if (!this.isDragging || !this.activeColumn) return;

      this.isDragging = false;

      const { length, loadMethod } = {
        province: {
          length: this.displayProvinces.length,
          loadMethod: 'selectProvince',
        },
        city: {
          length: this.displayCities.length,
          loadMethod: 'selectCity',
        },
        area: {
          length: this.displayAreas.length,
          loadMethod: 'selectArea',
        },
      }[this.activeColumn];

      const wrapper = e.currentTarget;
      wrapper.style.transition = 'none'; // 先关闭过渡

      // === 1. 惯性滑动：基于速度继续滑动 ===
      let finalTranslateY = this.currentTranslateY;
      let currentVelocity = this.velocity * 100; // 放大速度影响
      const friction = 0.92; // 阻力系数（越小越快停下）
      const minVelocity = 0.5; // 停止惯性最小速度

      const animate = () => {
        if (Math.abs(currentVelocity) < minVelocity) {
          // 惯性结束，开始对齐
          this.finishScroll(wrapper, loadMethod, length);
          return;
        }

        currentVelocity *= friction;
        finalTranslateY += currentVelocity;

        // 边界限制（可选：加弹性效果）
        const maxScroll = 0;
        const minScroll = -(length * this.optionHeight - this.selectHeight);
        if (finalTranslateY > maxScroll) {
          finalTranslateY = maxScroll + (finalTranslateY - maxScroll) * 0.2; // 回弹
          currentVelocity *= 0.5; // 碰边减速
        } else if (finalTranslateY < minScroll) {
          finalTranslateY = minScroll - (minScroll - finalTranslateY) * 0.2;
          currentVelocity *= 0.5;
        }

        this.currentTranslateY = finalTranslateY;
        wrapper.style.transform = `translateY(${finalTranslateY}px)`;

        requestAnimationFrame(animate);
      };

      // 开始惯性动画
      requestAnimationFrame(animate);

      this.activeColumn = null;
    },
    finishScroll(wrapper, loadMethod, length) {
      const visibleCenter = this.selectHeight / 2;
      const offset = this.currentTranslateY - visibleCenter;
      let targetIndex = Math.round(-offset / this.optionHeight);
      targetIndex = Math.max(0, Math.min(length - 1, targetIndex));

      // ✅ 触发选择逻辑
      this[loadMethod](targetIndex);

      // ✅ 添加对齐动画
      const targetY = this.getTranslateY(targetIndex);
      wrapper.style.transition = 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)';
      wrapper.style.transform = `translateY(${targetY}px)`;

      // 同步 currentTranslateY
      this.currentTranslateY = targetY;
    },
    getTranslateY(index) {
      const visibleCenter = this.selectHeight / 2;
      const itemCenter = index * this.optionHeight + this.optionHeight * 0.5;
      const offset = this.optionHeight * (this.alignOffsetRatio - 1);
      return visibleCenter - itemCenter + offset;
    },

    // 加载所有省份
    async loadProvinces() {
      try {
        const res = await axios.get('http://hmajax.itheima.net/api/province');
        const list = res.data.list || [];
        this.provinces = list.map((name, i) => ({
          value: `p-${i}`,
          label: name,
          children: null, // 标记未加载
        }));
      } catch (err) {
        console.error('获取省份失败:', err);
        this.$message?.error?.('省份数据加载失败') || alert('省份加载失败');
      }
    },

    // 选择省份
    async selectProvince(index) {
      if (index === this.selectedProvinceIndex) return;

      this.selectedProvinceIndex = index;

      if (index === 0) {
        // “请选择”
        this.cities = [];
        this.areas = [];
        this.showCityColumn = false;
        this.showAreaColumn = false;
      } else {
        const province = this.provinces[index - 1];

        // 懒加载市
        if (province.children === null) {
          try {
            const res = await axios.get('http://hmajax.itheima.net/api/city', {
              params: { pname: province.label },
            });
            const list = res.data.list || [];

            // 更新该省的 children
            this.$set(
              province,
              'children',
              list.map((name, i) => ({
                value: `${province.value}-c-${i}`,
                label: name,
                children: null, // 区也延迟加载
              }))
            );
          } catch (err) {
            console.error(`加载【${province.label}】的市失败`, err);
            this.$set(province, 'children', []);
          }
        }

        this.cities = province.children;
        this.selectedCityIndex = 0;
        this.selectedAreaIndex = 0;
        this.areas = [];
        this.showCityColumn = true;
        this.showAreaColumn = false;
      }

      this.$nextTick(() => this.animateColumn(this.$refs.provinceOptions));
    },

    // 选择城市
    async selectCity(index) {
      if (index === this.selectedCityIndex) return;

      this.selectedCityIndex = index;

      if (index === 0) {
        this.areas = [];
        this.selectedAreaIndex = 0;
        this.showAreaColumn = false;
      } else {
        const city = this.cities[index - 1];
        const province = this.provinces[this.selectedProvinceIndex - 1];

        // 懒加载区
        if (city.children === null) {
          try {
            const res = await axios.get('http://hmajax.itheima.net/api/area', {
              params: { pname: province.label, cname: city.label },
            });
            const list = res.data.list || [];

            this.$set(
              city,
              'children',
              list.map((name, i) => ({
                value: `${city.value}-a-${i}`,
                label: name,
              }))
            );
          } catch (err) {
            console.error(
              `加载【${province.label}-${city.label}】的区失败`,
              err
            );
            this.$set(city, 'children', []);
          }
        }

        this.areas = city.children;
        this.selectedAreaIndex = 0;
        this.showAreaColumn = true;
      }

      this.$nextTick(() => this.animateColumn(this.$refs.cityOptions));
    },

    // 选择区
    selectArea(index) {
      if (index === this.selectedAreaIndex) return;

      this.selectedAreaIndex = index;
      this.$nextTick(() => this.animateColumn(this.$refs.areaOptions));
    },

    animateColumn(refs) {
      if (!refs || !refs.length) return;
      const wrapper =
        refs[0].parentNode.parentNode.querySelector('.options-wrapper');
      if (wrapper) {
        wrapper.style.transition = 'transform 0.3s ease';
        this.$nextTick(() => {
          setTimeout(() => {
            wrapper.style.transition = '';
          }, 300);
        });
      }
    },

    cancel() {
      this.$emit('update:isShow', false);
    },

    confirm() {
      let result = { province: null, city: null, area: null };

      if (this.selectedProvinceIndex > 0) {
        const p = this.provinces[this.selectedProvinceIndex - 1];
        result.province = { value: p.value, label: p.label };
      }

      if (this.showCityColumn && this.selectedCityIndex > 0) {
        const c = this.cities[this.selectedCityIndex - 1];
        result.city = { value: c.value, label: c.label };
      }

      if (this.showAreaColumn && this.selectedAreaIndex > 0) {
        const a = this.areas[this.selectedAreaIndex - 1];
        result.area = { value: a.value, label: a.label };
      }

      this.$emit('confirm', result);
      this.$emit('update:isShow', false);
    },
  },
};
</script>
<style lang="scss" scoped>
.area_popup {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 42%;
  background-color: #fff;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  border-radius: 10px 10px 0 0;
  z-index: 2025;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: all 0.3s ease;
  transform: translateY(100%);

  &.active {
    transform: translateY(0);
  }
}

.area_popup_header {
  display: flex;
  justify-content: space-between;
  padding: 12px 16px;
  background-color: #f8f8f8;
  font-size: 16px;
  font-weight: 600;
  color: #333;
  position: relative;
  overflow: hidden;
  z-index: 1000;
}

.select-row {
  display: flex;
  justify-content: flex-start;
  flex: 1;
  padding: 10px;
  background-color: #f9f9f9;
  position: relative;
}

.select-col {
  width: 30%;
  text-align: center;
  margin: 0 1.5%;
}

.select-viewport {
  margin: 0 auto;
  width: 100%;
  height: 150px; // 你设置的 selectHeight
  border-radius: 5px;
  position: relative;
}

.options-wrapper {
  transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  transform-style: preserve-3d;
  backface-visibility: hidden;
  will-change: transform; // 提升性能
}

.option {
  padding: 10px;
  font-size: 16px;
  color: #333;
  cursor: pointer;
  height: 40px;
  display: flex;
  align-items: center;
  white-space: nowrap;
  font-size: 16px;
  justify-content: center;
  -webkit-tap-highlight-color: transparent;
  box-sizing: border-box;
}

.option.selected {
  font-weight: bold;
  color: #000;
}

// 分隔线（可选）
.select-line {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  transform: translateY(-70%);
  height: 44px;
  border-top: 1px solid #eee;
  border-bottom: 1px solid #eee;
  pointer-events: none; // 避免干扰点击
}

.mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 999;
  transition: all 0.3s ease;
  opacity: 0;
  visibility: hidden;

  &.active {
    opacity: 1;
    visibility: visible;
  }
}
</style>
